#include "stdafx.h"
#include "FlexibleMemory.h"

CFlexibleMemory* CFlexibleMemory::createNewFlexibleMemory(int int_one_frame_size, int int_frame_count)
{
	return new CFlexibleMemory(int_one_frame_size, int_frame_count);
}

CFlexibleMemory::CFlexibleMemory(int int_one_frame_size, int int_frame_count)
{
	m_int_one_frame_size = int_one_frame_size;
	m_int_frame_count = int_frame_count;

	m_lst_flags = NULL;
	m_ptr_buffers = NULL;

	InitCritical(m_cs_flags);

	AllocationMemory();
}

CFlexibleMemory::~CFlexibleMemory(void)
{
	DeletionMemory();

	DeleteCritical(m_cs_flags);
}

void CFlexibleMemory::AllocationMemory()
{
	//DeletionMemory();

	m_lst_flags = new byte[m_int_frame_count];
	memset(m_lst_flags, 0, m_int_frame_count);

	m_ptr_buffers = new char[m_int_frame_count * m_int_one_frame_size];
}

void CFlexibleMemory::DeletionMemory()
{
	if (m_lst_flags)
		delete[] m_lst_flags;

	if (m_ptr_buffers)
		delete[] m_ptr_buffers;

	m_lst_flags = NULL;
	m_ptr_buffers = NULL;
}

void CFlexibleMemory::ResetMemory()
{
	DeletionMemory();
	AllocationMemory();
}

void CFlexibleMemory::Lock()
{
	EnterCritical(m_cs_flags);
}

void CFlexibleMemory::Unlock()
{
	LeaveCritical(m_cs_flags);
}

char* CFlexibleMemory::AttachBufferPointer()
{
	char* ptr_temp_buffer = NULL;

	if (m_ptr_buffers == NULL)
		AllocationMemory();

	int int_counter = 0;
	while (TRUE)
	{
		int i = int_counter % m_int_frame_count;
		if (int_counter != 0 && i == 0)
		{
			Sleep(1);
		}

		int_counter++;

		Lock();
		if (m_lst_flags[i] == 0)
		{
			m_lst_flags[i] = 1;
			ptr_temp_buffer = m_ptr_buffers + i * m_int_one_frame_size;
			Unlock();

			break;
		}

		Unlock();
	}

	return ptr_temp_buffer;
}

void CFlexibleMemory::DetachBufferPointer(char* ptr_one_frame)
{
	int int_index = (ptr_one_frame - m_ptr_buffers) / m_int_one_frame_size;
	if (int_index >= m_int_frame_count)
		return;

	Lock();
	m_lst_flags[int_index] = 0;
	Unlock();
}

